import tkinter as tk
from tkinter import *
import keyboard     # pip install keyboard
from sys_config import *

class TabHeader():
    #初始化：容器、列定义、排序后的回调
    def __init__(self, container, def_col, order_cb):
        self.container  = container
        self.def_col    = def_col
        self.order_cb   = order_cb
        self.order_char = ['◊', '▲', '▼'] #▲▼◊，如果最后一个符号不是这三个之一表示不能排序；◊->▲, ▲->▼,▼->▲
        self.col_caption= [] #列文本
        self.col_click  = [] #列点击顺序
        self.first_label= False
        self.config     = SysConfig()
        self.config.init()

        self.create_labels()

    """根据排序方式，取得列文字的表示符号
    order           排序方式
    ready_to_order  是否返回准备排序（未排序）
    """
    def get_order_char(self, order, ready_to_order):
        if order == '':
            return self.order_char[0]
        if order == 'asc':
            if ready_to_order:
                return self.order_char[0]
            else:
                return self.order_char[1]
        if order == 'desc':
            if ready_to_order:
                return self.order_char[0]
            else:
                return self.order_char[2]

        return ''   
    
    """标签点击事件处理函数
    Args:
        index: 标签的索引编号
        label: 被点击的标签组件引用
        def_col: 列的数组
        label_caption: 标签文本的数组
        order_method: 排序符号
    """
    def on_label_click(self, index, label):
        is_ctrl = keyboard.is_pressed('ctrl')   # ctrl键是否被按下；按下时保留其他列的排序，只改变当前列；未按下时，其他列复位，改变当前列
        s = self.col_caption[index].get()
        str_caption = s[:-1]
        str_tail    = s[-1]    #最后一位

        label_width = label.winfo_width()
        print("on_label_click", index, s, is_ctrl, str_tail, f"Label的宽度是: {label_width}px") 

        col = self.def_col[index]
        if col['order'] == '_not_': #当前列不能排序，直接退出
            return
        
        if is_ctrl:
            # 按下时保留其他列的排序，只改变当前列；
            # 将当前列号放到最前面
            try:
                col_click_index = self.col_click.index(index)
            except ValueError:
                col_click_index = -1

            if col_click_index >= 0:
                del self.col_click[col_click_index]

            self.col_click.insert(0, index)

        else:
            # 未按下时，其他列复位，改变当前列
            for i in range(len(self.def_col)):
                col = self.def_col[i]
                self.col_caption[i].set(col['caption'] + self.get_order_char(col['order'], True))
            self.col_click = [index]


        # 改变当前列文本
        if self.order_char.count(str_tail) > 0:
            if str_tail == self.order_char[0]:
                self.col_caption[index].set(str_caption + self.order_char[1])

            if str_tail == self.order_char[1]:
                self.col_caption[index].set(str_caption + self.order_char[2])

            if str_tail == self.order_char[2]:
                self.col_caption[index].set(str_caption + self.order_char[1])

        # 输出排序SQL
        order_exp = []
        for i in range(len(self.col_click)):
            s = self.col_caption[self.col_click[i]].get()
            str_tail = s[-1]    #最后一位

            if str_tail == self.order_char[1]:
                order_exp.append(self.def_col[self.col_click[i]]['field'] + ' ASC')
            if str_tail == self.order_char[2]:
                order_exp.append(self.def_col[self.col_click[i]]['field'] + ' DESC')
        print("输出排序SQL:", ','.join(order_exp))
        self.order_cb(','.join(order_exp))
        # 添加动画效果
        original_bg = label.cget("bg")
        label.config(bg="#E8E6FF")  # 浅蓝色背景作为点击反馈
        label.after(300, lambda l=label, color=original_bg: l.config(bg=color)) # 0.3秒后恢复原始背景色

        self.get_char_width()


    """创建多个标签并设置点击事件"""        
    def create_labels(self):
        font_size = self.config.value('ui', 'font_size', 12)
        # 生成列显示文本
        for i in range(len(self.def_col)):
            label_var = StringVar()
            col = self.def_col[i]
            label_var.set(col['caption'] + self.get_order_char(col['order'], False))
            self.col_caption.append(label_var)
            
        # 创建多个标签
        max_width = 0
        max_width_index = 0
        lbl_list = []
        for i in range(len(self.def_col)):
            # 创建标签
            label = tk.Label(
                self.container,
                anchor      = self.def_col[i]['align'],
                textvariable= self.col_caption[i],
                width       = self.def_col[i]['width'] + 1, 
                height      = 2,   # 44
                relief="raised",  # 边框样式
                borderwidth = 1,
                bg="#F0F8FF",  # 浅蓝色背景
                font=('宋体', font_size),
                cursor="hand2"  # 鼠标悬停时变为手型
            )
            label.pack(side='left')

            if max_width < self.def_col[i]['width']:
                max_width = self.def_col[i]['width']
                max_width_index = i
            #保存第一个标签，用于计算平均字符宽度
            # if i == 0:
            #     self.first_label = label

            # 绑定点击事件（通过lambda传递额外的参数）
            label.bind(
                "<Button-1>", 
                lambda event, idx=i, lbl=label: self.on_label_click(idx, lbl)
            )
            lbl_list.append(label)
        #保存最宽的标签，用于计算平均字符宽度
        print("max_width_index", max_width_index)
        self.first_label = lbl_list[max_width_index]
        self.lbl_list = lbl_list

    def get_char_width(self):
        """取得一个字符的像素宽度
        """
        if self.first_label:
            label_width = self.first_label.winfo_width()
            avg_char_width = label_width / self.first_label['width']
            print("计算平均字符宽度", f"label_width:{label_width},width:{self.first_label['width']}, avg_char_width:{avg_char_width}")
            return avg_char_width
        else:
            return 0
        
    def get_width_list(self):
        """取得像素宽度的列表
        """
        ret = []
        for l in self.lbl_list:
            ret.append(l.winfo_width())
        return ret
